#region The MIT License
// The MIT License
// 
// Copyright (c) 2009 octalforty studios
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#endregion
using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.IO;

using octalforty.Componento.ComponentModel.Caching;
using octalforty.Componento.ComponentModel.Installation.FileSystem;
using octalforty.Componento.ComponentModel.Tracing;
using octalforty.Componento.Shared.SemanticModel;
using octalforty.Componento.Util;

namespace octalforty.Componento.ComponentModel.Installation
{
    /// <summary>
    /// A <see cref="IResourceInstaller"/> implementation which installs resources directly from Componento cache.
    /// </summary>
    [ResourceInstaller(Priority = 2000)]
    public class CacheResourceInstaller : IResourceInstaller
    {
        #region Public Properties
        public ITraceManagerService TraceManager
        { get; set; }

        public ITrace Trace
        { get; set;  }

        [Import()]
        public IFileSystemManagerService FileSystemManager 
        { get; set; }

        [Import()]
        public ICacheManagerService CacheManager 
        { get; set; }

        [Import()]
        public IResourceInstallerService ResourceInstaller 
        { get; set; }
        #endregion

        [ImportingConstructor()]
        public CacheResourceInstaller(ITraceManagerService traceManager)
        {
            TraceManager = traceManager;
            Trace = TraceManager.GetTrace(GetType().Name);
        }

        #region IResourceInstaller Members
        /// <summary>
        /// Verifies whether current <see cref="IResourceProvider"/> can install resources from <paramref name="resourceUri"/>.
        /// </summary>
        /// <param name="resourceUri"></param>
        /// <returns></returns>
        public bool CanInstallResourceFrom(Uri resourceUri)
        {
            return resourceUri.Scheme.StartsWith("cache+");
        }

        /// <summary>
        /// Installs resources from <paramref name="resourceUri"/> to <paramref name="destinationPathRoot"/>.
        /// </summary>
        /// <param name="resourceUri"></param>
        /// <param name="destinationPathRoot"></param>
        /// <param name="pathMapping"></param>
        public void InstallResource(Uri resourceUri, string destinationPathRoot, PathMapping pathMapping)
        {
            #region Tracing
            Trace.Verbose("Installing from cache from '{0}'", resourceUri);
            TraceManager.BeginLogicalOperation();
            #endregion

            //
            // Extract content to a temp folder
            var originalUri = new Uri(resourceUri.ToString().Substring(6));
            var content = CacheManager.Get(originalUri.ToString());

            var resourceName = UriUtil.GetLastSegment(originalUri);

            var path = Path.Combine(FileSystemManager.TempDirectory, resourceName);

            #region Tracing
            Trace.Verbose("Extracting cached resource to '{0}'", path);
            #endregion

            using(var fileStream = FileSystemManager.CreateFile(path))
                fileStream.Write(content, 0, content.Length);

            #region Tracing
            Trace.Verbose("Installing resource");
            TraceManager.BeginLogicalOperation();
            #endregion

            ResourceInstaller.InstallResources(new Uri[] { new Uri(path) }, destinationPathRoot, pathMapping);

            #region 
            TraceManager.EndLogicalOperation();
            Trace.Verbose("Installed resource");

            #endregion

            FileSystemManager.DeleteFile(path);

            #region Tracing
            TraceManager.EndLogicalOperation();
            Trace.Verbose("Installed from cache");
            #endregion

        }
        #endregion
    }
}
